<div dir="ltr">Thank you Andrei.<br><div>Also this unchecked fcntl call already exists for another lock type so we&#39;ll send a patch to fix both of them.</div></div><div class="gmail_extra"><br><div class="gmail_quote">2017-01-05 4:47 GMT+03:00 Andrei Vagin <span dir="ltr">&lt;<a href="mailto:avagin@virtuozzo.com" target="_blank">avagin@virtuozzo.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Tue, Dec 20, 2016 at 01:24:38PM +0300, Pavel Begunkov wrote:<br>
&gt; From: Begunkov Pavel &lt;<a href="mailto:asml.silence@gmail.com">asml.silence@gmail.com</a>&gt;<br>
&gt;<br>
&gt; OFD locks logic reuses existing locks c/r functionality.<br>
&gt;<br>
&gt; Signed-off-by: Begunkov Pavel &lt;<a href="mailto:asml.silence@gmail.com">asml.silence@gmail.com</a>&gt;<br>
&gt; Signed-off-by: Eugene Batalov &lt;<a href="mailto:eabatalov89@gmail.com">eabatalov89@gmail.com</a>&gt;<br>
&gt; ---<br>
&gt;  criu/file-lock.c         | 80 ++++++++++++++++++++++++++++++<wbr>++++++++++++++++--<br>
&gt;  criu/include/file-lock.h |  8 +++++<br>
&gt;  criu/proc_parse.c        |  2 ++<br>
&gt;  3 files changed, 87 insertions(+), 3 deletions(-)<br>
&gt;<br>
&gt; diff --git a/criu/file-lock.c b/criu/file-lock.c<br>
&gt; index 1ab1e58..fbb963b 100644<br>
&gt; --- a/criu/file-lock.c<br>
&gt; +++ b/criu/file-lock.c<br>
&gt; @@ -204,6 +204,57 @@ static int lock_check_fd(int lfd, struct file_lock *fl)<br>
&gt;       return 1;<br>
&gt;  }<br>
&gt;<br>
&gt; +static int lock_ofd_check_fd(int lfd, struct file_lock *fl)<br>
&gt; +{<br>
&gt; +     int ret;<br>
&gt; +<br>
&gt; +     struct flock lck = {<br>
&gt; +             .l_whence = SEEK_SET,<br>
&gt; +             .l_type   = F_WRLCK,<br>
&gt; +             .l_start  = fl-&gt;start<br>
&gt; +     };<br>
&gt; +     if (strcmp(fl-&gt;end, &quot;EOF&quot;)) {<br>
&gt; +             unsigned long end;<br>
&gt; +<br>
&gt; +             ret = sscanf(fl-&gt;end, &quot;%lu&quot;, &amp;end);<br>
&gt; +             if (ret &lt;= 0) {<br>
&gt; +                     pr_err(&quot;Invalid lock entry\n&quot;);<br>
&gt; +                     return -1;<br>
&gt; +             }<br>
&gt; +             lck.l_len = end - fl-&gt;start + 1;<br>
&gt; +     } else {<br>
&gt; +             lck.l_len = 0;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     ret = fcntl(lfd, F_OFD_SETLK, &amp;lck);<br>
&gt; +     pr_debug(&quot;   `- %d/%d\n&quot;, ret, errno);<br>
&gt; +     if (ret != 0) {<br>
&gt; +             if (errno != EAGAIN) {<br>
&gt; +                     pr_err(&quot;Bogus lock test result %d\n&quot;, ret);<br>
&gt; +                     return -1;<br>
&gt; +             }<br>
&gt; +<br>
&gt; +             return 0;<br>
&gt; +     } else {<br>
&gt; +             /*<br>
&gt; +              * The ret == 0 means, that new lock doesn&#39;t conflict<br>
&gt; +              * with any others on the file. But since we do know,<br>
&gt; +              * that there should be some other one (file is found<br>
&gt; +              * in /proc/locks), it means that the lock is already<br>
&gt; +              * on file pointed by fd.<br>
&gt; +              */<br>
&gt; +             pr_debug(&quot;   `- downgrading lock back\n&quot;);<br>
&gt; +             if (fl-&gt;fl_ltype &amp; LOCK_WRITE)<br>
&gt; +                     lck.l_type = F_WRLCK;<br>
&gt; +             else<br>
&gt; +                     lck.l_type = F_RDLCK;<br>
&gt; +<br>
&gt; +             fcntl(lfd, F_OFD_SETLK, &amp;lck);<br>
<br>
<br>
</div></div>CID 173734 (#1 of 1): Unchecked return value from library (CHECKED_RETURN)<br>
7. check_return: Calling fcntl(lfd, 37, &amp;lck) without checking return<br>
value. This library function may fail and return an error code.<br>
<div><div class="h5"><br>
&gt; +     }<br>
&gt; +<br>
&gt; +     return 1;<br>
&gt; +}<br>
&gt; +<br>
&gt;  int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)<br>
&gt;  {<br>
&gt;       struct file_lock *fl;<br>
&gt; @@ -232,11 +283,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)<br>
&gt;                        */<br>
&gt;                       if (fl-&gt;fl_owner != pid-&gt;real)<br>
&gt;                               continue;<br>
&gt; -             } else /* fl-&gt;fl_kind == FL_FLOCK */ {<br>
&gt; +             } else /* fl-&gt;fl_kind == FL_FLOCK || fl-&gt;fl_kind == FL_OFD */ {<br>
&gt;                       int ret;<br>
&gt;<br>
&gt;                       /*<br>
&gt; -                      * FLOCKs can be inherited across fork,<br>
&gt; +                      * OFD locks &amp; FLOCKs can be inherited across fork,<br>
&gt;                        * thus we can have any task as lock<br>
&gt;                        * owner. But the creator is preferred<br>
&gt;                        * anyway.<br>
&gt; @@ -247,7 +298,11 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)<br>
&gt;                               continue;<br>
&gt;<br>
&gt;                       pr_debug(&quot;Checking lock holder %d:%d\n&quot;, pid-&gt;real, fd);<br>
&gt; -                     ret = lock_check_fd(lfd, fl);<br>
&gt; +                     if (fl-&gt;fl_kind == FL_FLOCK)<br>
&gt; +                             ret = lock_check_fd(lfd, fl);<br>
&gt; +                     else<br>
&gt; +                             ret = lock_ofd_check_fd(lfd, fl);<br>
&gt; +<br>
&gt;                       if (ret &lt; 0)<br>
&gt;                               return ret;<br>
&gt;                       if (ret == 0)<br>
&gt; @@ -312,6 +367,25 @@ static int restore_file_lock(<wbr>FileLockEntry *fle)<br>
&gt;                       pr_err(&quot;Can not set posix lock!\n&quot;);<br>
&gt;                       goto err;<br>
&gt;               }<br>
&gt; +     } else if (fle-&gt;flag &amp; FL_OFD) {<br>
&gt; +             struct flock flk = {<br>
&gt; +                     .l_whence = SEEK_SET,<br>
&gt; +                     .l_start  = fle-&gt;start,<br>
&gt; +                     .l_len    = fle-&gt;len,<br>
&gt; +                     .l_pid    = 0,<br>
&gt; +                     .l_type   = fle-&gt;type<br>
&gt; +             };<br>
&gt; +<br>
&gt; +             pr_info(&quot;(ofd)flag: %d, type: %d, pid: %d, fd: %d, &quot;<br>
&gt; +                             &quot;start: %8&quot;PRIx64&quot;, len: %8&quot;PRIx64&quot;\n&quot;,<br>
&gt; +                             fle-&gt;flag, fle-&gt;type, fle-&gt;pid, fle-&gt;fd,<br>
&gt; +                             fle-&gt;start, fle-&gt;len);<br>
&gt; +<br>
&gt; +             ret = fcntl(fle-&gt;fd, F_OFD_SETLK, &amp;flk);<br>
&gt; +             if (ret &lt; 0) {<br>
&gt; +                     pr_err(&quot;Can not set ofd lock!\n&quot;);<br>
&gt; +                     goto err;<br>
&gt; +             }<br>
&gt;       } else {<br>
&gt;               pr_err(&quot;Unknown file lock style!\n&quot;);<br>
&gt;               goto err;<br>
&gt; diff --git a/criu/include/file-lock.h b/criu/include/file-lock.h<br>
&gt; index 5c1bb5b..c3f2dab 100644<br>
&gt; --- a/criu/include/file-lock.h<br>
&gt; +++ b/criu/include/file-lock.h<br>
&gt; @@ -9,6 +9,7 @@<br>
&gt;  #define FL_UNKNOWN   -1<br>
&gt;  #define FL_POSIX     1<br>
&gt;  #define FL_FLOCK     2<br>
&gt; +#define FL_OFD               4<br>
&gt;<br>
&gt;  /* for posix fcntl() and lockf() */<br>
&gt;  #ifndef F_RDLCK<br>
&gt; @@ -17,6 +18,13 @@<br>
&gt;  #define F_UNLCK              2<br>
&gt;  #endif<br>
&gt;<br>
&gt; +/* for OFD locks fcntl() */<br>
&gt; +#ifndef F_OFD_GETLK<br>
&gt; +#define F_OFD_GETLK  36<br>
&gt; +#define F_OFD_SETLK  37<br>
&gt; +#define F_OFD_SETLKW 38<br>
&gt; +#endif<br>
&gt; +<br>
&gt;  /* operations for bsd flock(), also used by the kernel implementation */<br>
&gt;  #define LOCK_SH              1       /* shared lock */<br>
&gt;  #define LOCK_EX              2       /* exclusive lock */<br>
&gt; diff --git a/criu/proc_parse.c b/criu/proc_parse.c<br>
&gt; index 7c48b33..1f0bff8 100644<br>
&gt; --- a/criu/proc_parse.c<br>
&gt; +++ b/criu/proc_parse.c<br>
&gt; @@ -1973,6 +1973,8 @@ static int parse_file_lock_buf(char *buf, struct file_lock *fl,<br>
&gt;               fl-&gt;fl_kind = FL_POSIX;<br>
&gt;       else if (!strcmp(fl_flag, &quot;FLOCK&quot;))<br>
&gt;               fl-&gt;fl_kind = FL_FLOCK;<br>
&gt; +     else if (!strcmp(fl_flag, &quot;OFDLCK&quot;))<br>
&gt; +             fl-&gt;fl_kind = FL_OFD;<br>
&gt;       else<br>
&gt;               fl-&gt;fl_kind = FL_UNKNOWN;<br>
&gt;<br>
&gt; --<br>
&gt; 2.10.0<br>
&gt;<br>
</div></div>&gt; ______________________________<wbr>_________________<br>
&gt; CRIU mailing list<br>
&gt; <a href="mailto:CRIU@openvz.org">CRIU@openvz.org</a><br>
&gt; <a href="https://lists.openvz.org/mailman/listinfo/criu" rel="noreferrer" target="_blank">https://lists.openvz.org/<wbr>mailman/listinfo/criu</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Best regards,<br>Eugene Batalov.</div>
</div>