This file is indexed.

/lib/bilibop/lockfs_mount_helper is in bilibop-lockfs 0.4.23.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#!/bin/sh
set -e

# /lib/bilibop/lockfs_mount_helper {{{
# Mount helper script for 'lockfs' filesystem type entries in /etc/fstab.
# This script cannot be run manually. The expected way to run it is the
# following:
# 1. Enable bilibop-lockfs:
#    * set BILIBOP_LOCKFS to "true" in /etc/bilibop/bilibop.conf or
#    * append 'lockfs' parameter in the boot commandline
# 2. One time '/' is an aufs mountpoint, the temporary /etc/fstab is
#    modified to replace filesystem types (third field) of some entries
#    by 'lockfs' (options are modified too to remember the original
#    fstype).
# 3. /sbin/mount.lockfs is created if it don't already exist. This can be a
#    symlink to /lib/bilibop/lockfs_mount_helper if this helper is executable,
#    or a copy of the helper (followed by chmod +x) if the helper is not
#    executable. If the helper is missing, /sbin/mount.lockfs will be a
#    poor fallback to call mount normally.
# 4. /etc/fstab is parsed by 'mount -a', and then mount calls mount.lockfs
#    with the proper arguments when a 'lockfs' fstype is encountered.
# }}}

PATH="/sbin:/bin"

usage() {
    cat <<EOF
${0##*/}: mount helper script for bilibop-lockfs.
This script can not be run manually, but only by a mount process,
and only if bilibop-lockfs is enabled.
EOF
}

# mount_fallback() =========================================================={{{
# What we want is: mount a device on its original mountpoint and rewrite the
# fstab entry to keep it consistent. This function should be called in case of
# error or if the device is whitelisted. This function parses the arguments of
# the script itself (i.e. mount_fallback "$@").
mount_fallback() {
    ${DEBUG} && echo "> mount_fallback $@" >&2
    local opt options= fstype=
    for opt in $(IFS=','; echo ${4}); do
        case "${opt}" in
            fstype=*)
                eval "${opt}"
                ;;
            *)
                options="${options:+${options},}${opt}"
                ;;
        esac
    done
    sed -i "s;^\s*\([^#][^ ]\+\s\+${2}\s\+\)lockfs\s.*;\1${fstype:-auto} ${options:-defaults} 0 0;" /etc/fstab
    mount ${flags} ${1} ${2} ${fstype:+-t ${fstype}} ${options:+-o ${options}}
}
# ===========================================================================}}}

# Works only if the parent process is /bin/mount:
if [ "$(readlink -f /proc/${PPID}/exe)" != "/bin/mount" ]; then
    usage >&2
    exit 3
fi

. /lib/bilibop/common.sh
get_bilibop_variables
get_udev_root

# Works only if the root filesystem is already managed by bilibop-lockfs:
if is_aufs_mountpoint -q / && [ -f "${BILIBOP_RUNDIR}/lock" ]; then
    LOCKFS="true"
    robr="$(aufs_readonly_branch /)"
    rwbr="$(aufs_writable_branch /)"
else
    echo "${0##*/}: bilibop-lockfs is disabled." >&2
    exit 1
fi

# Some configurations can have been overridden from the boot commandline:
for param in $(cat /proc/cmdline); do
    case "${param}" in
        lockfs=*)
            for policy in $(IFS=','; echo ${param#lockfs=}); do
                case "${policy}" in
                    default)
                        BILIBOP_LOCKFS_POLICY=""
                        BILIBOP_LOCKFS_WHITELIST=""
                        BILIBOP_LOCKFS_SIZE=""
                        ;;
                    hard|soft)
                        BILIBOP_LOCKFS_POLICY="${policy}"
                        ;;
                    all)
                        BILIBOP_LOCKFS_WHITELIST=""
                        ;;
                    -/*)
                        BILIBOP_LOCKFS_WHITELIST="${BILIBOP_LOCKFS_WHITELIST:+${BILIBOP_LOCKFS_WHITELIST} }${policy#-}"
                        ;;
                esac
            done
            ;;
    esac
done

# But if there is a physical lock, it takes precedence:
if [ -f "${BILIBOP_RUNDIR}/plocked" ]; then
    . ${BILIBOP_RUNDIR}/plocked
fi

# the mount(8) command, after parsing commandline arguments and/or /etc/fstab,
# always provides arguments to the helper scripts in this order:
# FILESYSTEM MOUNTPOINT [FLAGS] -o MOUNTOPTIONS
# where FLAGS are generic, not filesystem specific: -n, -s, -v for example; -r
# (or --read-only) and -w (or --rw or --read-write) are translated to -o ro and
# -o rw respectively by the mount command itself.

while [ "${1}" ]; do
    case "${1}" in
        -o)
            MNTARGS="${MNTARGS:+${MNTARGS} }${1} ${2}"
            shift 2
            ;;
        -*)
            # Do not skip other options (-n, -s, -v), but take them
            # apart: we will reuse them for each mount invocation.
            flags="${flags:+${flags} }${1}"
            shift
            ;;
        *)
            MNTARGS="${MNTARGS:+${MNTARGS} }${1}"
            shift
            ;;
    esac
done

# Reinitialize script arguments
eval set -- "${MNTARGS}"

if [ -b "${1}" ]; then
    device="${1}"
    # Check if this device is whitelisted:
    if [ -n "${BILIBOP_LOCKFS_WHITELIST}" ]; then
        # Query ID_FS_* udev environment variables of the device:
        eval $(query_udev_envvar $(readlink -f ${device}))
        if [ -z "${ID_FS_USAGE}" ]; then
            eval $(blkid -o udev -p ${device})
        fi
        [ "${ID_FS_USAGE}" = "filesystem" -o "${ID_FS_USAGE}" = "crypto" ] &&
        for skip in ${BILIBOP_LOCKFS_WHITELIST}; do
            case "${skip}" in
                UUID=${ID_FS_UUID}|LABEL=${ID_FS_LABEL}|TYPE=${ID_FS_TYPE})
                    LOCKFS="false"
                    break
                    ;;
            esac
        done
    fi

elif [ -f "${1}" ]; then
    lofile="${1}"
    LOFILE="${robr}${lofile}"

else
    # There is no block device to mount (here 'block device' includes
    # files associated to a loop device). Bind mounts and remote fs
    # should have been discarded by the bilibop-lockfs script in the
    # initramfs...
    LOCKFS="false"
fi

# If bilibop-lockfs is not enabled (the device is whitelisted, or we don't
# know how to manage it), rewrite the fstab entry and do a normal mount:
if [ "${LOCKFS}" != "true" ]; then
    mount_fallback "${@}"
    exit $?
fi

mntpnt="${2}"
options="${4}"

# Parse mount options. Two cases:
# 1. the block device will be mounted with the same options than in the
#    original fstab entry, plus 'ro'.
# 2. the tmpfs will be mounted with only some options of the previous:
#    ro, nodev, noexec, nosuid, if they exist.

for opt in $(IFS=','; echo ${options}); do
    # 1. Options for the readonly branch:
    case "${opt}" in
        fstype=*)
            eval "${opt}"
            ;;
        rw)
            ;;
        *)
            robr_opts="${robr_opts:+${robr_opts},}${opt}"
            ;;
    esac

    # 2. Options for the writable branch:
    case "${opt}" in
        ro|nodev|noexec|nosuid)
            rwbr_opts="${rwbr_opts:+${rwbr_opts},}${opt}"
            ;;
        *)
            ;;
    esac
done

# Each readonly branch is mounted under the subtree of the main readonly
# branch (/aufs/ro) and each writable branch is mounted under the subtree
# of the main writable branch (/aufs/rw):
robr="${robr}${mntpnt}"
rwbr="${rwbr}${mntpnt}"

# If the policy is not explicitly set to 'soft', set the block device as
# readonly, and use 'rr' aufs option to improve performances:
if [ "${BILIBOP_LOCKFS_POLICY}" = "soft" ]; then
    RO="ro"
else
    RO="rr"
    [ -b "${device}" ] && blockdev --setro ${device}
fi

# Try to mount the readonly branch. In case of failure, undo what has been
# done before, do a normal mount, rewrite the fstab entry to be consistent
# with that, and exit:
if ! mount ${flags} ${fstype:+-t ${fstype}} -o ${robr_opts:+${robr_opts},}ro ${device:-${LOFILE}} ${robr}; then
    [ "${RO}" = "rr" ] && [ -b "${device}" ] && blockdev --setrw "${device}"
    mount_fallback "${@}"
    exit 3
fi

# The amount of RAM to allow to this mountpoint:
SIZE=
for size in ${BILIBOP_LOCKFS_SIZE}; do
    case "${size}" in
        ${mntpnt}=[1-9]*)
            SIZE="$(printf "${size#${mntpnt}=}" | grep '^[1-9][0-9]*[KkMmGg%]\?$')"
            break
            ;;
    esac
done

# Create the mountpoint (it should not exist before this step):
if [ ! -d "${rwbr}" ]; then
    mkdir -p ${rwbr}
    grep -q "^${mntpnt}$" ${BILIBOP_RUNDIR}/lock ||
    echo "${mntpnt}" >>${BILIBOP_RUNDIR}/lock
fi

# Try to mount the writable branch, and in case of failure, undo what
# has been done before, etc.
if ! mount ${flags} -t tmpfs -o ${rwbr_opts:+${rwbr_opts},}${SIZE:+size=${SIZE},}mode=0755 tmpfs ${rwbr}; then
    umount ${robr}
    [ "${RO}" = "rr" ] && [ -b "${device}" ] && blockdev --setrw "${device}"
    mount_fallback "${@}"
    exit 3
fi

# Fix permissions and ownership of the writable branch (and catch the values;
# they will be reused later):

mod="$(LC_ALL=C chmod -v --reference="${robr}" "${rwbr}" | sed 's;.* \([0-7]\{4\}\) (.\+)$;\1;')"
own="$(LC_ALL=C chown -v --reference="${robr}" "${rwbr}" | sed 's;.* \([^:]\+:[^:]\+\)$;\1;')"

owner="${own%:*}"
if [ "${owner}" != "root" ]; then
    uid="$(grep "^${owner}:" /etc/passwd | sed 's;^\([^:]*:\)\{2\}\([^:]\+\):.*;\2;')"
fi

group="${own#*:}"
if [ "${group}" != "root" ]; then
    gid="$(grep "^${group}:" /etc/group | sed 's;^\([^:]*:\)\{2\}\([^:]\+\):.*;\2;')"
fi

# Try to mount the aufs now. In case of failure, undo what has been done
# before, etc.
if ! mount ${flags} -t aufs -o br:${rwbr}=rw:${robr}=${RO} none ${mntpnt}; then
    umount ${robr}
    umount ${rwbr}
    [ "${RO}" = "rr" ] && [ -b "${device}" ] && blockdev --setrw "${device}"
    mount_fallback "${@}"
    exit 3
fi

# All is OK. So we can rewrite fstab entry to reflect the real mounts. This
# can be important for clean unmounts at shutdown (for the case a filesystem
# is remounted rw during a session).
robr_line="${device:-${LOFILE}} ${robr} ${fstype:-auto} ${robr_opts:+${robr_opts},}ro 0 0"
rwbr_line="tmpfs ${rwbr} tmpfs ${rwbr_opts:+${rwbr_opts},}${SIZE:+size=${SIZE},}${uid:+uid=${uid},}${gid:+gid=${gid},}mode=${mod} 0 0"
aufs_line="none ${mntpnt} aufs br:${rwbr}=rw:${robr}=${RO} 0 0"

sed -i "s;^\s*[^#][^ ]\+\s\+${mntpnt}\s\+lockfs\s.*;${robr_line}\n${rwbr_line}\n${aufs_line};" /etc/fstab

# vim: et sts=4 sw=4 ts=4